<template>
  <div class="table-content">
    <div class="table-tools">
      <div class="table-search">
        <slot name="easySearch"></slot>
      </div>
      <div class="btns">
        <slot name="buttons"></slot>
        <Button @click="config = !config" shape="circle"  icon="md-build" title="设置"></Button>
      </div>
    </div>
    <div class="table-main" ref="main">
      <div class="tree ivu-table-stripe ivu-table">
        <table cellspacing="0" cellpadding="0" border="0" class="wp100">
          <thead>
            <tr>
              <th
                v-for="(column, index) in columnNow"
                :key="index"
                :style="tdStyle(column)"
              >
                <label v-if="column.type === 'selection'">
                  <Checkbox
                    v-model="checkAll"
                    @on-change="allChecked"
                    :indeterminate="indeterminate"
                  ></Checkbox>
                </label>
                <label v-else>
                  {{ renderHeader(column, index) }}
                  <span class="ivu-table-sort" v-if="column.sortable">
                    <Icon
                      type="arrow-up-b"
                      :class="{ on: column._sortType === 'asc' }"
                      @click.native="handleSort(index, 'asc')"
                    />
                    <Icon
                      type="arrow-down-b"
                      :class="{ on: column._sortType === 'desc' }"
                      @click.native="handleSort(index, 'desc')"
                    />
                  </span>
                </label>
              </th>
            </tr>
          </thead>
          <tbody class="ivu-table-body">
            <tr
              v-for="(item, index) in trs"
              :key="item.id"
              class="ivu-table-row"
              :id="'tr' + index"
              v-show="show(item)"
              :draggable="drag && !item._drag"
              @dragstart="dragstart($event, index, item)"
              @drop="dragdrop($event, index, item)"
              @dragenter="dragenter($event, index, item)"
              @dragover="dragover($event, index, item)"
              @dragleave="dragleave($event, index, item)"
            >
              <!--  -->
              <td
                v-for="(column, snum) in columnNow"
                :key="column.key"
                :style="tdStyle(column)"
              >
                <!-- 多选 -->
                <label
                  v-if="column.type === 'selection'"
                >
                  <Checkbox
                    v-model="item._checked"
                    @on-change="rowChecked($event,item, index,)"
                    :indeterminate="indeterminateBoys(item)"
                  ></Checkbox>
                </label>

                <Icon
                  v-if="column.type === 'drag'"
                  type="md-more"
                  class="drag"
                />
                <DTSpan
                  v-if="column.type == 'date'"
                  :value="item[column.key]"
                />
                <div v-if="column.type == 'user'">
                  <User :value="item[column.key]" />
                </div>
                <div
                  v-if="
                    column.type == 'users' &&
                    item[column.key] &&
                    item[column.key].length > 0
                  "
                >
                  <User
                    v-for="li in item[column.key]"
                    :value="li"
                    :key="li"
                    class="ml10"
                  />
                </div>
                <state
                  v-if="column.code"
                  :code="column.code"
                  :value="item[column.key]"
                />
                <!-- 树图标 -->
                <span @click="toggle(index, item)" v-if="snum == treeColumn()">
                  <span class="ib" v-width="spaceWidth * item._level"></span>
                  <a v-if="item._count > 0" class="ivu-table-cell-tree">
                    <Icon
                      :type="!item._expanded ? 'ios-add' : 'ios-remove'"
                    /> </a
                  ><i v-else class="ms-tree-space"></i>
                </span>
                <!-- 菜单名称、排序、请求地址 -->
                <label
                  v-if="
                    !column.type &&
                    !column.code &&
                    !column.render &&
                    !column.slot
                  "
                >
                  {{ renderBody(item, column) }}
                </label>
                <table-expand
                  v-if="column.render && !column.type && !column.solt"
                  :row="item"
                  :column="column"
                  :index="snum"
                  :render="column.render"
                ></table-expand>
                <column-slot
                  v-if="column.slot"
                  :row="item"
                  :column="column"
                  :index="snum"
                ></column-slot>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
    <div class="table-footer">
      <slot name="footer"></slot>
      <Page
        v-if="page"
        :total="search.total"
        :current="search.page"
        class="fr"
        show-total
        size="small"
        show-elevator
        show-sizer
        :page-size="search.pageSize"
        :page-size-opts="pageSizeOpts"
        @on-change="pageChange"
        @on-page-size-change="pageSizeChange"
      />
    </div>
    <Modal
      v-if="high"
      v-model="modalSearch"
      title="高级搜索"
      draggable
      width="800"
      ref="search"
    >
      <slot name="searchForm"></slot>
      <div slot="footer">
        <Button @click="modalSearch = false" class="mr20">取消</Button>
        <Button @click="complexSearch" type="primary" class="mr20">查询</Button>
      </div>
    </Modal>
    <Drawer
      title="列设置"
      v-if="set"
      v-model="config"
      :scrollable="true"
      placement="left"
      :mask="false"
    >
      <div slot="header">
        列设置
        <!-- <a @click="undoConfig" class="ml50">
          <Icon type="md-refresh" title="恢复初始设置" />
        </a> -->
      </div>
      <ul class="table-columns">
        <li
          v-for="(li, index) in columnsCur"
          :key="index"
          v-dragging="{ item: li, list: columnsCur, group: 'li' }"
        >
          <label @click="columnChange(li, index)" :class="{ dis: li.hide }">
            <Icon
              :type="li.hide ? 'md-eye-off' : 'md-eye'"
              size="16"
              class="mr10"
            />
            <span>{{ li.title }}</span>
          </label>
          <Icon type="ios-move" class="move" size="18" />
        </li>
      </ul>
    </Drawer>
    <FooterToolbar v-if="batch" v-show="footerToolbar&&selectItems.length>0" class="ftball">
      <div class="ib">已选{{ selectItems.length }}项</div>
      <slot name="batch"></slot>
      <Button @click="cancelBatch">取消</Button>
    </FooterToolbar>
  </div>
</template>

<script>
import TableExpand from "./components/expand";
import ColumnSlot from "./components/columnSolt";
export default {
  name: "TreeGrid",
  components: {
    TableExpand,
    ColumnSlot,
  },
  props: {
    mode: {
      type: [String, Number],
      default: 0,
      validator: (v) => {
        var modes = ["read", "column", "row"];
        if (/^\d+/.test(v)) {
          return v >= 0 && v < modes.length;
        }
        return modes.indexOf(v) > -1;
      },
    },
    border: {
      //是否显示边框
      type: Boolean,
      default: true,
    },
    batch: {
      //是否批量操作
      type: Boolean,
      default: true,
    },
    format: {
      type: Function,
      default: null,
    },
    initsearch: {
      type: Function,
      default: null,
    },
    lazy: {
      //懒加载设置，设置为真时候，默认不加载数据。
      type: Boolean,
      default: false,
    },
    placeholder: {
      type: String,
      default: "请输入关键字",
    },
    height: {
      type: Number,
      default: 0,
    },
    tool: {
      //是否显示工具栏
      type: Boolean,
      default: true,
    },
    easy: {
      //是否显示简单搜索
      type: Boolean,
      default: true,
    },
    high: {
      //是否显示高级搜索
      type: Boolean,
      default: true,
    },
    draggable: {
      //是否可以拖拽
      type: Boolean,
      default: false,
    },
    set: {
      //是否显示列设置
      type: Boolean,
      default: true,
    },
    page: {
      //是否分页
      type: Boolean,
      default: false,
    },
    columns: Array,
    items: {
      //接收树形数据
      type: Array,
      default() {
        return [];
      },
    },
    data: {
      //接收UpId型数据
      type: Array,
      default() {
        return [];
      },
    },
    keyname: {
      //默认行主键
      type: [String],
      default: "id",
    },
    upname: {
      // 父级字段名称
      type: String,
      default: "upId",
    },
    root: {
      // 根级UpId的值.
      type: [String, Number],
      default: 0,
    },
    action: {
      //接口地址
      type: String,
      default: "",
    },
    conditions: {
      //查询条件
      type: Object,
      default: function () {
        return {
          keys: {
            op: "name",
            value: "",
            default: true,
          },
        };
      },
    },
    iconName: false,
    drag: {
      //拖拽
      type: Boolean,
      default: false,
    },
    spaceWidth: {
      //树形表格缩进距离
      type: Number,
      default: 35,
    },
    exportTitle: {
      type: String,
      default: "",
    },
  },
  provide() {
    return {
      tableRoot: this.slots,
    };
  },
  data() {
    return {
      color: "#19be6b",
      checkAll: false,
      keys: "",
      selectItems: [],
      modalSearch: false,
      footerToolbar: false,
      search: {
        pageIndex: 1,
        pageSize: 20,
        sortBy: "id",
        isDesc: true,
        conditions: [],
      },
      level:1,
      searchConditions: this.search,
      pageSizeOpts: [20, 50, 100],
      tableHeight: 0,
      firstY: 0,
      config: false,
      logs: [],
      trs: [], // 处理后数据数组
      columnsCur: [], // 处理后的表头数据
      checkGroup: [], // 复选框数组
      checks: false, // 全选
      timer: false, // 控制监听时长
      dataLength: 0, // 树形数据长度
      dragIndex: -1, //拖拽开始的序号
      allUser: [], //所有user
      userConfig: null, 
      userId: this.$store.state.userInfo.userId,
    };
  },
  computed: {
    indeterminate() {
      var checkeds = this.trs.filter((u) => {
        return u._checked;
      }).length;
      return 0 < checkeds && checkeds < this.trs.length;
    },
    columnNow() {
      // return this.columnsCur;
      var now=this.columnsCur.filter((u) => {
        return !u.hide||u.hide==false;
      });
      console.log("cols",now,this.columnsCur,this.columns)
      return now;
    },
  },
  watch: {
    items() {
      this.selectItems=[];
      if (this.items) {
        this.trs = this.treeToList(this.items);
      }
    },
    data(v) {},
    columns: {
      handler() {
        this.columnsCur = this.makeColumns();
      },
      deep: true,
    },
    exportTitle(v) {
      this.exportTitle = v;
    },
  },
  created(){
     this.columnsCur = this.makeColumns();
  },
  mounted() {
    if (this.items && this.items.length > 0) {
      this.trs = this.treeToList(this.items);
    }
  },
  methods: {
    load() {},
    complexSearch() {
      var search = this.$refs.search.$children.filter((u) => {
        return u.condition;
      });
      if (search) {
        var conditions = search[0].condition;
        this.reload(conditions);
      }
    },
    slots() {
      return this.$scopedSlots;
    },
    //拖拽开始
    dragstart(e, index, row) {
      this.dragIndex = index;
      console.log(index);
    },
    //进入
    dragenter(e, index, row) {
      var tr = document.getElementById("tr" + index);
      if (this.dragIndex > index) {
        tr.className += " move";
      } else if (this.dragIndex < index) {
        tr.className += " sort";
      }
    },
    //  悬浮
    dragover(e, index, row) {
      e.preventDefault();
      // 鼠标Y
      var my = e.offsetY;
      var h = e.toElement.clientHeight;
      var tr = document.getElementById("tr" + index);
      if (this.dragIndex > index && my / h < 0.5) {
        tr.className = tr.className.replace(" move", " sort");
      }
      if (this.dragIndex < index && my / h > 0.5) {
        tr.className = tr.className.replace(" sort", " move");
      }
    },
    // 离开
    dragleave(e, index, row) {
      var tr = document.getElementById("tr" + index);
      tr.className = tr.className.replace(" move", "").replace(" sort", "");
    },
    //放下
    dragdrop(e, index, row) {
      event.preventDefault();
      var tr = document.getElementById("tr" + index);
      tr.className = tr.className.replace(" move", "").replace(" sort", "");
      if (index != this.dragIndex) {
        this.$emit("on-drag-drop", this.dragIndex, index, this.trs, e);
      }
    },
    /**
         *   @dragover="dragover($event, index, item)"
              @dragleave="dragleave($event,index,item)"
         */
    // 有无多选框折叠位置优化
    treeColumn() {
      var num = 0;
      for (let i = 0, len = this.columnNow.length; i < len; i++) {
        if (this.columnNow[i].tree) {
          num = i;
        }
      }
      return num;
    },

    // 设置td宽度,td的align
    tdStyle(column) {
      const style = {};
      if (column.align) {
        style["text-align"] = column.align;
      }
      if (column.width) {
        style["width"] = `${column.width}px`;
      }
      if (column.hide) {
        style["display"] = `none`;
      }
      return style;
    },
    // 排序事件
    handleSort(index, type) {
      this.columnsCur.forEach((col) => (col._sortType = "normal"));
      if (this.columnsCur[index]._sortType === type) {
        this.columnsCur[index]._sortType = "normal";
      } else {
        this.columnsCur[index]._sortType = type;
      }
      this.$emit(
        "on-sort-change",
        this.columnsCur[index].key,
        this.columnsCur[index]._sortType
      );
    },
    // 点击某一行事件
    RowClick(data, event, index, text) {
      this.$emit("on-row-click", data, event, index, text);
    },
    // 点击事件 返回数据处理
    // 处理表头数据
    makeColumns() {
      const columns = this.$u.clone(this.columns);
      return columns;
    },
    // //  隐藏显示

    toggle(index, item) {
      if (item._count > 0) {
        this.$set(this.trs[index], "_expanded", !item._expanded);
        this.trs.forEach((u, i) => {
          if (u[this.upname] === item.id) {
            this.$set(this.trs[i], "_show", !item._expanded);
          }
        });
      }
    },
    show(item) {
      if (item._level == 0) {
        return true;
      } else {
        var parents = this.getRoots(item);
        return (
          parents.filter((u) => {
            return !u._expanded;
          }).length == 0
        );
      }
    },
    getRoots(item) {
      var parents = [];
      var root = this.trs.filter((u) => {
        return u[this.keyname] == item[this.upname];
      });
      while (root.length == 1) {
        parents.push(root[0]);
        root = this.trs.filter((u) => {
          return u[this.keyname] === root[0][this.upname];
        });
      }
      return parents;
    },
    // 点击check勾选框,判断是否有children节点 如果有就一并勾选
    rowChecked(event,data, index, ) {
      this.trs[index]._checked=data._checked;
      var boys = this.getChildrens(data);
      if (boys.length>0) {
              this.trs.forEach((u, i) => {
        var items = boys.filter((b) => {
          return b[this.keyname] == u[this.keyname];
        });
        if (items.length == 1) {
          this.$set(this.trs[i], "_checked", data._checked);
        }
      });
      }
      this.checkAll =
        this.trs.length >
        this.trs.filter((u) => {
          return !u._checked;
        }).length;
      this.$nextTick(() => {
        this.selectionChange();
      });
    },
    indeterminateBoys(item){
      var boys = this.getChildrens(item);
      if(boys.length==0){
        return false;
      }else{
        return boys.filter(u=>{return u._checked===item._checked}).length<boys.length;
      }
    },
    getChildrens(data) {
      var childrens = [];
      var that = this;
      getChildren(data);
      function getChildren(f) {
        that.trs.forEach((u) => {
          if (u[that.upname] == f[that.keyname]) {
            childrens.push(u);
            getChildren(u);
          }
        });
      }
      return childrens;
    },
    // checkbox 全选 选择事件
    allChecked(v) {
      this.trs.forEach((u, i) => {
        this.$set(this.trs[i], "_checked", v);
      });
      this.$nextTick(() => {
        this.selectionChange();
      });
    },
    selectionChange() {
      var items = this.trs.filter((u) => {
        return u._checked;
      });
      this.selectItems = items;
      this.$emit("on-selection-change", items, this.trs);
      this.footerToolbar = items.length > 0;
      console.log("footerToolbar", items);
    },
    // 数组去重
    getArray(a) {
      const hash = {};
      const len = a.length;
      const result = [];
      for (let i = 0; i < len; i++) {
        if (!hash[a[i]]) {
          hash[a[i]] = true;
          result.push(a[i]);
        }
      }
      return result;
    },
    All(data) {
      let arr = [];
      data.forEach((item) => {
        arr.push(item.id);
        if (item.children && item.children.length > 0) {
          arr = arr.concat(this.All(item.children));
        }
      });
      return arr;
    },

    // 返回表头
    renderHeader(column, $index) {
      if ("renderHeader" in this.columns[$index]) {
        return this.columns[$index].renderHeader(column, $index);
      }
      return column.title || "#";
    },
    treeToList(tree) {
      var that = this;
      let list = [];

      function treeToList(data, level) {
        data.map((u) => {
          let copy = that.$u.clone(u);
          copy._count = 0;
          copy._level = level;
          copy._expanded = copy._expanded || that.level > level;
          copy._show = true;
          copy._indeterminate = false;
          copy._checked = copy._checked || false;
          list.push(copy);

          if (u.children) {
            treeToList(u.children, level + 1);
            copy._count = u.children.length;
            delete copy.children;
          }
        });
      }
      treeToList(tree, 0);
      return list;
    },

    // 返回内容
    renderBody(row, column, index) {
      return row[column.key];
    },
    //分页选择
    pageChange(page) {
      this.search.page = page;
      this.search.pageIndex = page;
      this.load();
    },
    pageSizeChange(size) {
      this.search.pageSize = size;
      this.search.pageIndex = 1;
      this.load();
    },
    columnChange(item, i) {
      item.hide = !item.hide;
      this.$set(this.columnsCur, item, i);
      // this.saveUserconfig();
    },
    undoConfig() {
      //列设置恢复初始化
      this.columnsCur = this.$u.clone(this.columns);
      // this.saveUserconfig();
    },
    saveUserconfig() {
      let url = `${window.systemUrl}/config/update`;
      var content = [];
      this.columnsCur.map((u) => {
        content.push({
          key: u.key,
          hide: u.hide,
        });
      });
      if (!this.userConfig) {
        url = `${window.systemUrl}/config/create`;
        var data = {
          page: window.location.pathname,
          component: "Grid",
          key: this.$u.guid(),
          content: JSON.stringify(content),
        };
        this.$api.post(url, data).then((r) => {
          this.loadUserConfig();
        });
      } else {
        this.userConfig.content = JSON.stringify(content);
        this.$api.post(url, this.userConfig);
      }
    },
    //批量取消
    cancelBatch() {
      this.footerToolbar = false;
      // this.$refs.table.selectAll(false);
    },
  },
};
</script>
